home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / vanessa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  11.5 KB  |  365 lines

  1. /* Vanessa Board Interface, 7.1.92
  2.  * implemented by Marcel Wiget, HB9RWM
  3.  * for NOS (Copyright 1991 Phil Karn, KA9Q)
  4.  *
  5.  * Vanessa is part of the project SEPRAN,
  6.  * Swiss Experimental Packet Radio Amateur Network,
  7.  * of the SWISS-ARTG (Swiss Amateur Radio Teleprinter Group).
  8.  * The full-size XT-Board contains 2 seperate interfaces
  9.  * for high-speed AX.25 Layer-2 data streams. The data
  10.  * can be received and sent via Dual-Port RAM embedded in a
  11.  * KISS - Frame. Result: very less overhead for NOS to receive
  12.  * and send a frame (e.g. only 1 memcpy for the hole frame).
  13.  *
  14.  * 10.11.91: Support of Vanessa Version 3.0 (word allignement RAM)
  15.  *           param command support
  16.  *           statistic support (e.g. if va0)
  17.  * 14.11.91: set of Node ID and Alias
  18.  *           safe waiting for cmd completion
  19.  * 19.11.91: info for 2nd port was wrong
  20.  * 20.11.91: download added
  21.  * 21.11.91: statistics for port 1 corrected, mbuf handling
  22.  * 17.11.91: some adaptions made for use with WNOS - DB3FL
  23.  * 24.11.91: dirps() and restore() inserted to mask interrupts
  24.  *           and changed buffer allocations and statistics
  25.  *           'param'-command adapted to WNOS strategy
  26.  *  7.01.92: if_param no longer supported by wnos, removed.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <dos.h>        /* for MK_FP */
  31. #include "global.h"
  32. #include "config.h"
  33. #ifdef VANESSA
  34. #include "proc.h"
  35. #include "commands.h"
  36. #include "mbuf.h"
  37. #include "ax25.h"
  38. #include "ip.h"         /* def. Ip_Addr */
  39. #include "pktdrvr.h"    /* def. for CL_AX25 */
  40. #include "trace.h"
  41. #include "vanessa.h"
  42.  
  43. static struct vandrvr Vandrvr[VAN_MAX];
  44.  
  45. /* Attach a Vanessa interface to the system
  46.  * One board has 2 interfaces (Port 0 and 1)
  47.  * Each Port must have its own interface,
  48.  * attached via different dpram_base (dual port ram base address)
  49.  * argv[0]: hardware type, must be "vanessa"
  50.  * argv[1]: interface label, e.g., "va0"
  51.  * argv[2]: port-nr, started with 0,1: board 0, with 2,3: board 1 etc.
  52.  * argv[3]: maximum transmission unit, bytes (MTU) (optional)
  53.  */
  54.  
  55. int
  56. van_attach(argc,argv,p)
  57. int argc;
  58. char *argv[];
  59. void *p;
  60. {
  61.         struct iface *ifvan;
  62.         struct vandrvr *vp;
  63.         struct dp_record far *dp;
  64.         unsigned char *cp;
  65.         int i;
  66.  
  67.         if(if_lookup(argv[1]) != NULLIF){
  68.                 tprintf(Ifexist,argv[1]);
  69.                 return -1;
  70.         }
  71.         if(*Mycall == '\0') {                         /* better to be sure */
  72.             tputs(Nomycall);
  73.             return -1;
  74.         }
  75.         for (i = 0; i < VAN_MAX; i++){
  76.                 if(Vandrvr[i].iface == NULLIF)
  77.                         break;
  78.         }
  79.         if (i >= VAN_MAX){
  80.                 tprintf("Max %d Vanessa drivers\n",VAN_MAX);
  81.                 return -1;
  82.         }
  83.         /* Create interface structure and fill in details */
  84.         ifvan = (struct iface *)mxallocw(sizeof(struct iface));
  85.         ifvan->addr = Ip_addr;
  86.         ifvan->name = strxdup(argv[1]);
  87.         ifvan->mtu = (4 == argc) ? atoi(argv[3]) : 256;
  88.         setencap(ifvan,"AX25");
  89.         ifvan->ioctl = van_ioctl;
  90.         ifvan->status = van_status;
  91.         ifvan->raw = van_raw;
  92.         ifvan->stop = van_stop;
  93.         ifvan->hwaddr = strxdup(Mycall);
  94.         ifvan->dev = i;
  95.         vp = &Vandrvr[i];
  96.         vp->portnr = htoi(argv[2]);
  97.         vp->dpram_base = MK_FP(BASE_SEGMENT + (vp->portnr << 8),0);
  98.         vp->ioled = BASE_IO + (vp->portnr & 1) + (vp->portnr >> 1)*8 + 6;
  99.         vp->iores = BASE_IO + (vp->portnr >> 1)*8;
  100.         vp->iface = ifvan;
  101.         van_reset(vp);
  102.  
  103.         /* if port 0 of selected board, then */
  104.         /* set Node ID etc. */
  105.         dp = vp->dpram_base;
  106.         if (0 == (vp->portnr & 1)) {
  107.                 /* ok, let's do it */
  108.                 cp = dp->dp_cData;
  109.                 memcpy(cp,Mycall,AXALEN);        /* MY_ID */
  110.                 cp += AXALEN;
  111.                 memcpy(cp,Mycall,AXALEN);               /* MY_ALIAS */
  112.                 cp += AXALEN;
  113.                 *cp = (char) (0xff & vp->portnr);
  114.                 dp->dp_cCMD = CMD_ID_LOAD;
  115.         }
  116.  
  117.         outportb(vp->ioled,LED_OFF);
  118.  
  119.         /* init statistics */
  120.         vp->nTXwait     = 0;
  121.         vp->nRXmaxlen   = 0;
  122.         vp->nTXmaxlen   = 0;
  123.  
  124.         init_maxheard(ifvan);
  125.         init_flags(ifvan);
  126.  
  127.         ifvan->proc = newproc("van rx",256,van_rx,ifvan->dev,NULL,NULL,0);
  128.  
  129.         /* Link in the interface */
  130.         ifvan->next = Ifaces;
  131.         ifvan->niface = Niface++;               /* WNOS router */
  132.         Ifaces = ifvan;
  133.  
  134.         return 0;
  135. }
  136.  
  137. /* van_ioctl:
  138.  * perform device control on VANESSA KISS
  139.  */
  140. static int
  141. van_ioctl(iface,argc,argv)
  142. struct iface *iface;
  143. int argc;
  144. char *argv[];
  145. {
  146.         struct vandrvr *vp = &Vandrvr[iface->dev];
  147.         struct dp_record far *p = vp->dpram_base;
  148.         int pn = 0, v, i;
  149.  
  150.         if (2 == argc) {
  151.                 /* set value */
  152.                 pn = atoi(argv[0]);             /* param-nr to change */
  153.                 v = (int16)atoi(argv[1]);       /* value to be loaded */
  154.         }
  155.         for(i = 1;i < PARAM_COUNT; i++) {
  156.                 switch(i) {
  157.                 case TXDELAY:
  158.                         if (i==pn) {
  159.                                 p->dp_pTXDelay = v;
  160.                         } else {
  161.                                 tprintf("TxDelay %d\n", p->dp_pTXDelay);
  162.                         }
  163.                         break;
  164.                 case PERSIST:
  165.                         if (i==pn) {
  166.                                 p->dp_pPersist = v;
  167.                         } else {
  168.                                 tprintf("Persistence %d\n", p->dp_pPersist);
  169.                         }
  170.                         break;
  171.                 case SLOTTIME:
  172.                         if (i==pn) {
  173.                                 p->dp_pSlottime = v;
  174.                         } else {
  175.                                 tprintf("SlotTime %d\n", p->dp_pSlottime);
  176.                         }
  177.                         break;
  178.                 case TXTAIL:
  179.                         if (i==pn) {
  180.                                 p->dp_pTXTail = v;
  181.                         } else {
  182.                                 tprintf("TxTail %d\n", p->dp_pTXTail);
  183.                         }
  184.                         break;
  185.                 case FULLDUP:
  186.                         if (i==pn) {
  187.                                 p->dp_pDuplex = v;
  188.                         } else {
  189.                                 tprintf("Fullduplex %d\n", p->dp_pDuplex);
  190.                         }
  191.                         break;
  192.                 default:
  193.                         break;
  194.                 }
  195.                 if (pn){
  196.                         p->dp_reReadPar = 0;
  197.                 }
  198.         }
  199.         return 0;
  200. }
  201.  
  202. /* send raw data packet on KISS VANESSA */
  203. int
  204. van_raw(iface,data)
  205. struct iface *iface;
  206. struct mbuf *data;
  207. {
  208.         struct vandrvr *vp;
  209.         struct dp_record far *p;
  210.         int16 len = len_p(data);
  211.         int i_state;
  212.  
  213.         if (0 < len) {
  214.                 vp = &Vandrvr[iface->dev];
  215.                 dump(iface,IF_TRACE_OUT,CL_AX25,data);
  216.                 p = vp->dpram_base;
  217.                 if (0 == p->dp_oFProd)
  218.                         vp->nTXwait++;
  219.                 while ( (NULLIF != vp->iface) && (0 == p->dp_oFProd) ) {
  220.                         /* still busy, should not happen */
  221.                         pwait(NULL);
  222.                 }
  223.                 if (NULLIF != vp->iface) {
  224.                         /* send it */
  225.                         i_state = dirps();
  226.                         p->dp_oLFrm  = len;
  227.                         len=dqdata(data,(char *)&p->dp_oBuffer[0],len);
  228.                         if (len > vp->nTXmaxlen)
  229.                                 vp->nTXmaxlen = len;
  230.                         p->dp_oFProd = 0;                               /* send
  231. it */
  232.                         restore(i_state);
  233.                 }
  234.         } else
  235.                 free_p(data);
  236.         return 0;
  237. }
  238.  
  239. static void
  240. van_rx(dev,p1,p2)
  241. int dev;
  242. void *p1;
  243. void *p2;
  244. {
  245.         struct vandrvr *vp = &Vandrvr[dev];
  246.         struct mbuf *rcvbuf;
  247.         struct phdr phdr;
  248.         struct dp_record far *p = vp->dpram_base;
  249.         char *cp;
  250.         int16 len;
  251.         int i_state;
  252.  
  253.         while (vp->iface != NULLIF){
  254.                 if (0 == p->dp_iFProd) {
  255.                         /* data arrived */
  256.                         len = p->dp_iLFrm;
  257.                         if (len > vp->nRXmaxlen)
  258.                                 vp->nRXmaxlen = len;
  259.                         if (len > 0) {
  260.                                 i_state = dirps();
  261.                                 outportb(vp->ioled,LED_ON);
  262.                                 rcvbuf = ambufw(len+sizeof(phdr));
  263.  
  264.                                 cp = rcvbuf->data + sizeof(phdr);
  265.                                 memcpy(cp,(char *)&p->dp_iBuffer[0],len);
  266.                                 rcvbuf->cnt = sizeof(phdr) + len;
  267.                                 rcvbuf->next = NULLBUF;
  268.                                 phdr.iface = vp->iface;
  269.                                 phdr.type = CL_AX25;
  270.                                 memcpy(rcvbuf->data,(char *)&phdr,sizeof(phdr));
  271.                                 restore(i_state);
  272.                                 enqueue(&Hopper,rcvbuf);
  273.                         }
  274.                         outportb(vp->ioled,LED_OFF);
  275.                         p->dp_iFProd = 1;       /* open DPRAM for next frame */
  276.                 }
  277.                 pwait(NULL);
  278.         }
  279. }
  280.  
  281. /* shut down the VANESSA interface */
  282. static int
  283. van_stop(iface)
  284. struct iface *iface;
  285. {
  286.         struct vandrvr *vp = &Vandrvr[iface->dev];
  287.  
  288.         if (NULLIF != vp->iface) {
  289.                 vp->iface = NULLIF;
  290.         }
  291.         return 0;
  292. }
  293.  
  294. void
  295. van_reset(vp)
  296. struct vandrvr *vp;
  297. {
  298.         outportb(vp->iores,0xff);
  299.         pwait(NULL);
  300.         outportb(vp->iores,0);
  301. }
  302.  
  303.  
  304. int32
  305. cova(p,n)
  306. char *p;
  307. int16 n;
  308. {
  309.         int  i;
  310.         long rv = 0;
  311.         n--;
  312.         for (i=n;i>=0;i--) rv = (rv<<8)+(p[i]&0xff);
  313.         return rv;
  314. }
  315.  
  316.  
  317. /* Show vanessa port status */
  318. static int
  319. van_status(iface)
  320. struct iface *iface;
  321. {
  322.         struct vandrvr *vp = &Vandrvr[iface->dev];
  323.         char *cp;
  324.         int i;
  325.         int i_state;
  326.  
  327.         struct dp_record far *dp0 =
  328.             MK_FP(FP_SEG(vp->dpram_base)-((vp->portnr & 1)<<8),0);
  329.         struct dp_record far *dp1 =
  330.             MK_FP(FP_SEG(dp0)+0x0100,0);
  331.  
  332.         if (NULLIF != vp->iface) {
  333.                 i_state = dirps();
  334.                 dp0->dp_cCMD = CMD_POINTER;
  335.                 i = 0;
  336.                 while (i<CMD_TIMEOUT && dp1->dp_cCMD!=(CMD_POINTER|0xf000) ){
  337.                         i++;
  338.                         pwait(NULL);
  339.                 }
  340.                 if (CMD_TIMEOUT==i) {
  341.                         tputs("No valid data!\n");
  342.                 } else {
  343.                         tprintf("\n    Port %u: DP-RAM=%p TXwait=%u TXmaxlen=%u RXmaxlen=%u",
  344.                                 vp->portnr,vp->dpram_base,
  345.                                 vp->nTXwait,vp->nTXmaxlen,vp->nRXmaxlen);
  346.                         cp = dp1->dp_cData;
  347.                         tprintf("\n    SWrev=%x\.%02x Rst=%u Board=%u",
  348.                                 cp[cRev+1],cp[cRev],cova(&cp[cRst],2),cp[cPNr] & 0xf);
  349.                                 cp += (vp->portnr&1 ? cPort1 : 0);
  350.                         tprintf("    Counters: Rx=%lu Tx=%lu TxKu=%lu\n",
  351.                                 cova(&cp[cRx],3),cova(&cp[cTx],3),cova(&cp[cTxKu],3));
  352.                         tprintf("\n    RxBf TxBf RxBe TxBe RFlI TflC TFlI RCRC "
  353.                                 "RxOv TxTo SyTx SyRx RxAb TxUdr\n   ");
  354.                         for (i = cRxBf; i <= cTxUdr; i += 2)
  355.                                 tprintf("%5u",cova(&cp[i],2));
  356.                         tputs("\n");
  357.                 }
  358.                 restore(i_state);
  359.         }
  360.         return 0;
  361. }
  362.  
  363. #endif /* VANESSA */
  364.  
  365.